package net.bblbs.zhongrx.util;

import android.text.TextUtils;
import android.util.Log;
import org.apache.commons.io.FileUtils;
import org.json.JSONObject;
import org.w3c.dom.Text;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

public class HttpRequest {

    private static final String TAG = "ZRX_HTTPREQUEST";
    public static String mHeaderName = null;
    public static String mToken = null;
    public static String mSession = null;
    public static long mTime = 0;

    private static final String boundary =  "*****";
    private static final String crlf = "\r\n";
    private static final String twoHyphens = "--";

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param baseUrl   发送请求的 URL
     * @param request 请求参数，请求参数应该是 name1=value1&name2=value2 的形式或者JSON形式。
     * @return 所代表远程资源的响应结果
     */
    public static String post(String baseUrl, String apiPath, String request) { //apiPath e.g. "/auth/ajaxLogin/"
        Log.i("URL",baseUrl + apiPath);
        Log.i("Post Request",request);


        BufferedReader in = null;
        String result = "";
        try {
            //从服务器获取（GET方法） token和相关参数
            if ((null == mHeaderName) && (null == mToken) && (null==mSession)){
                getTokenParam(baseUrl);
//                Map<String, String> tokenParam = getTokenParam(baseUrl);
//                headerName = tokenParam.get("headerName");
//                token = tokenParam.get("token");
//                session = tokenParam.get("SessionID");
            }


            HttpURLConnection httpConn2 = (HttpURLConnection) new URL(baseUrl + apiPath).openConnection();
            httpConn2.setRequestMethod("POST");
            httpConn2.setDoOutput(true);
            httpConn2.setDoInput(true);
            httpConn2.setRequestProperty("Content-Type", "application/json");
            httpConn2.setRequestProperty("Accept", "application/json");
            httpConn2.setRequestProperty(mHeaderName, mToken);
            httpConn2.setRequestProperty("Cookie", "SESSION=" + mSession );
            if (!TextUtils.isEmpty(request)){
                httpConn2.getOutputStream().write(request.getBytes("utf-8"));
            }


            Log.d(TAG, "post headName:"+ mHeaderName + "\ntoken:" + mToken + "\nsession:" + mSession) ;

            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(httpConn2.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }

            Log.d(TAG, "Post Response:"+result);
        } catch (Exception e) {
            Log.e(TAG, "发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    public static void postWithCallback(final String baseUrl,final  String apiPath, final String request, final HttpCallbackListener listener) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                BufferedReader in = null;
                String result = "";
                HttpURLConnection httpConn2 = null;
                try {

                    if ((null == mHeaderName) && (null == mToken) && (null==mSession)){
                        getTokenParam(baseUrl);
                    }


                    httpConn2 = (HttpURLConnection) new URL(baseUrl + apiPath).openConnection();
                    httpConn2.setRequestMethod("POST");
                    httpConn2.setDoOutput(true);
                    httpConn2.setDoInput(true);
                    httpConn2.setRequestProperty("Content-Type", "application/json");
                    httpConn2.setRequestProperty("Accept", "application/json");
                    httpConn2.setRequestProperty(mHeaderName, mToken);
                    httpConn2.setRequestProperty("Cookie", "SESSION=" + mSession );
                    if (!TextUtils.isEmpty(request)){
                        httpConn2.getOutputStream().write(request.getBytes("utf-8"));
                    }


                    Log.d(TAG, "post headName:"+ mHeaderName + "\ntoken:" + mToken + "\nsession:" + mSession) ;

                    // 定义BufferedReader输入流来读取URL的响应
                    in = new BufferedReader(new InputStreamReader(httpConn2.getInputStream()));
                    int status = httpConn2.getResponseCode();
                    if (status!= 200){
                        listener.onError(new Exception("http response"+status));
                    }

                    String line;
                    while ((line = in.readLine()) != null) {
                        result += line;
                    }

                    Log.d(TAG, "Post Response:"+result);

                    if(listener !=null) {
                        listener.onFinish(result);
                    }

                } catch (Exception e) {
                    Log.e(TAG, "发送 POST 请求出现异常！" + e);
                    if(listener !=null) {
                        listener.onError(e);
                    }
                } finally {
                    if (httpConn2 !=null) {
                        httpConn2.disconnect();
                    }
                }
            }
        }).start();
    }

    public static void getWithCallback(final String baseUrl, final String apiPath, final HttpCallbackListener listener) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d("URL",baseUrl + apiPath);

                BufferedReader in = null;
                String result = "";
                HttpURLConnection connection = null;
                try {
                    //从服务器获取（GET方法） token和相关参数
//                    if ((null == headerName) && (null == token) && (null==session)){
//                        Map<String, String> tokenParam = getTokenParam(baseUrl);
//                        headerName = tokenParam.get("headerName");
//                        token = tokenParam.get("token");
//                        session = tokenParam.get("SessionID");
//                    }

                    connection = (HttpURLConnection) new URL(baseUrl + apiPath).openConnection();
                    connection.setDoOutput(true);
                    connection.setDoInput(true);
                    connection.setRequestProperty("Content-Type", "application/json");
                    connection.setRequestProperty("Accept", "application/json");
                    connection.setRequestProperty(mHeaderName, mToken);
                    connection.setRequestProperty("Cookie", "SESSION=" + mSession);

                    Log.d(TAG, "get headName:"+ mHeaderName + "\ntoken:" + mToken + "\nsession:" + mSession) ;

                    // 定义BufferedReader输入流来读取URL的响应
                    in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String line;
                    while ((line = in.readLine()) != null) {
                        result += line;
                    }
                    Log.d(TAG, "Get Response:"+result);

                    if(listener !=null) {
                        listener.onFinish(result);
                    }
                } catch (Exception e) {
                    Log.e(TAG, "发送 GET 请求出现异常！" + e);
                    if(listener !=null) {
                        listener.onError(e);
                    }
                } finally {
                    if (connection !=null) {
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }

    public static void uploadWithCallback(final String baseUrl, final String apiPath, final List<String> fileNames, final List<String> fileURLs, final HttpCallbackListener listener) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d("URL",baseUrl + apiPath);

                BufferedReader in = null;
                String result = "";
                HttpURLConnection connection = null;
                DataOutputStream request;

                try {
                    //从服务器获取（GET方法） token和相关参数
//                    if ((null == headerName) && (null == token) && (null==session)){
//                        Map<String, String> tokenParam = getTokenParam(baseUrl);
//                        headerName = tokenParam.get("headerName");
//                        token = tokenParam.get("token");
//                        session = tokenParam.get("SessionID");
//                    }

                    connection = (HttpURLConnection) new URL(baseUrl + apiPath).openConnection();
                    connection.setUseCaches(false);
                    connection.setDoOutput(true); // indicates POST method
                    connection.setDoInput(true);

                    connection.setRequestMethod("POST");
                    connection.setRequestProperty("Connection", "Keep-Alive");
                    connection.setRequestProperty("Cache-Control", "no-cache");
                    connection.setRequestProperty("Charsert", "UTF-8");
                    connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

                    connection.setRequestProperty(mHeaderName, mToken);
                    connection.setRequestProperty("Cookie", "SESSION=" + mSession);

                    request =  new DataOutputStream(connection.getOutputStream());

                    for(int i =0; i < fileNames.size(); i++){
                        String fileName = fileNames.get(i);

                        String contentType = fileName.contains("照片")?"image/jpeg":"video/mpeg4";


                        request.writeBytes(twoHyphens+boundary+crlf);
                        request.writeBytes(
                                "Content-Disposition: form-data; name=\"" + new String(fileName.getBytes("UTF-8"),"iso-8859-1") + "\"; filename=\"" + new String(fileName.getBytes("UTF-8"), "iso-8859-1") + "\""+crlf);
                        request.writeBytes(
                                "Content-Type:"+ contentType+crlf);
                        request.writeBytes("Content-Transfer-Encoding: binary"+crlf + crlf);
                        request.flush();
                        byte bytes[] = FileUtils.readFileToByteArray(new File(fileURLs.get(i)));
                        request.write(bytes);
                        request.flush();
                        request.writeBytes(crlf);
                        request.flush();
                    }

                    request.writeBytes(crlf+ twoHyphens + boundary + twoHyphens + crlf);

                    request.flush();
                    request.close();
                    int status = connection.getResponseCode();

                    in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String line;
                    while ((line = in.readLine()) != null) {
                        result += line;
                    }
                    Log.d(TAG, "Upload Response:"+result);


                    if(listener !=null) {
                        listener.onFinish(result);
                    }
                } catch (Exception e) {
                    Log.e(TAG, "upload file exception:" + e);
                    if(listener !=null) {
                        listener.onError(e);
                    }
                } finally {
                    if (connection !=null) {
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }

    public static boolean serviceUpload(final String baseUrl, final String apiPath, final String fileName, final String fileURL) {

        Log.d("URL",baseUrl + apiPath);

        BufferedReader in = null;
        String result = "";
        HttpURLConnection connection = null;
        DataOutputStream request;

        try {
            connection = (HttpURLConnection) new URL(baseUrl + apiPath).openConnection();
            connection.setUseCaches(false);
            connection.setDoOutput(true); // indicates POST method
            connection.setDoInput(true);

            connection.setRequestMethod("POST");
            connection.setRequestProperty("Connection", "Keep-Alive");
            connection.setRequestProperty("Cache-Control", "no-cache");
            connection.setRequestProperty("Charsert", "UTF-8");
            connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

            connection.setRequestProperty(mHeaderName, mToken);
            connection.setRequestProperty("Cookie", "SESSION=" + mSession);

            request =  new DataOutputStream(connection.getOutputStream());

            String contentType = fileName.contains("照片")?"image/jpeg":"video/mpeg4";
            request.writeBytes(twoHyphens+boundary+crlf);
            request.writeBytes(
                "Content-Disposition: form-data; name=\"" + new String(fileName.getBytes("UTF-8"),"iso-8859-1") + "\"; filename=\"" + new String(fileName.getBytes("UTF-8"), "iso-8859-1") + "\""+crlf);
            request.writeBytes(
                "Content-Type:"+ contentType+crlf);
            request.writeBytes("Content-Transfer-Encoding: binary"+crlf + crlf);
            request.flush();
            byte bytes[] = FileUtils.readFileToByteArray(new File(fileURL));
            request.write(bytes);
            request.flush();
            request.writeBytes(crlf);
            request.flush();


            request.writeBytes(crlf+ twoHyphens + boundary + twoHyphens + crlf);

            request.flush();
            request.close();
            int status = connection.getResponseCode();
            if (status!= 200){
                return false;
            }

            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            Log.d(TAG, "Upload Response:"+result);

            return true;
        } catch (Exception e) {
            Log.e(TAG, "upload file exception:" + e);
            return false;
        } finally {
            if (connection !=null) {
                connection.disconnect();
            }
        }
    }

    public static boolean serviceUpdate(String baseUrl, String apiPath, String request) { //apiPath e.g. "/auth/ajaxLogin/"


        Log.d("serviceUpdate URL",baseUrl + apiPath);

        BufferedReader in = null;
        String result = "";
        HttpURLConnection httpConn2 = null;

        try {

            httpConn2 = (HttpURLConnection) new URL(baseUrl + apiPath).openConnection();
            httpConn2.setRequestMethod("POST");
            httpConn2.setDoOutput(true);
            httpConn2.setDoInput(true);
            httpConn2.setRequestProperty("Content-Type", "application/json");
            httpConn2.setRequestProperty("Accept", "application/json");
            httpConn2.setRequestProperty(mHeaderName, mToken);
            httpConn2.setRequestProperty("Cookie", "SESSION=" + mSession );
            if (!TextUtils.isEmpty(request)){
                httpConn2.getOutputStream().write(request.getBytes("utf-8"));
            }

            int status = httpConn2.getResponseCode();
            if (status!= 200){
                return false;
            }

            Log.d(TAG, "post headName:"+ mHeaderName + "\ntoken:" + mToken + "\nsession:" + mSession) ;

            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(httpConn2.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }

            Log.d(TAG, "Post Response:"+result);
            return true;
        } catch (Exception e) {
            Log.e(TAG, "发送 POST 请求出现异常！" + e);
            e.printStackTrace();
            return false;
        } finally {
            if (httpConn2 !=null) {
                httpConn2.disconnect();
            }
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

    }

    public static void downloadFile(final String webURL, final String personId, final int actionId, final HttpCallbackListener listener) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d("download URL",webURL);

                BufferedReader in = null;
                String result = "";
                HttpURLConnection connection = null;
                DataOutputStream request;

                try {
                    URL url = new URL(webURL);
                    HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
                    httpConn.setRequestProperty(mHeaderName, mToken);
                    httpConn.setRequestProperty("Cookie", "SESSION=" + mSession);

                    int responseCode = httpConn.getResponseCode();

                    // always check HTTP response code first
                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        String fileName = "";
                        String disposition = httpConn.getHeaderField("Content-Disposition");
                        String contentType = httpConn.getContentType();
                        int contentLength = httpConn.getContentLength();

//                        if (disposition != null) {
//                            // extracts file name from header field
//                            int index = disposition.indexOf("filename=");
//                            if (index > 0) {
//                                fileName = disposition.substring(index + 10,
//                                        disposition.length() - 1);
//                            }
//                        } else {
//                            // extracts file name from URL
//                            fileName = "qxb.jpg";
//                        }
//
//                        System.out.println("Content-Type = " + contentType);
//                        System.out.println("Content-Disposition = " + disposition);
//                        System.out.println("Content-Length = " + contentLength);
//                        System.out.println("fileName = " + fileName);

                        // opens input stream from the HTTP connection
                        InputStream inputStream = httpConn.getInputStream();


                        //need to change null !!!!
                        File f = FileStoreUtil.setUpPhotoFile(personId, "", null);

                        // opens an output stream to save into file
                        FileOutputStream outputStream = new FileOutputStream(f);

                        int bytesRead = -1;
                        byte[] buffer = new byte[4096];
                        while ((bytesRead = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, bytesRead);
                        }

                        outputStream.close();
                        inputStream.close();

                        if(listener !=null) {
                            listener.onFinish(f.getAbsolutePath());
                        }

                    } else {

                    }
                    httpConn.disconnect();
                } catch (Exception e) {
                    Log.e(TAG, "upload file exception:" + e);
                    if(listener !=null) {
                        listener.onError(e);
                    }
                } finally {
                    if (connection !=null) {
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }

    //获取 Token和SessionID等参数
    public static void getTokenParam(String baseUrl) {
        String result="";
        BufferedReader in = null;
//        Map<String, String> tokenParam = new HashMap<String, String>();
        try {
            URL realUrl = new URL(baseUrl+"/auth/csrf");
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            conn.connect();
            // 获取所有响应头字段
            Map<String, List<String>> header = conn.getHeaderFields();
            List<String> cookies = header.get("Set-Cookie");
            String sessionid = "";
            for (String cookie : cookies) {
                if (cookie.contains("SESSION")) {
                    sessionid = cookie.split(";")[0].substring(8);
//                    tokenParam.put("SessionID", sessionid);
                    mSession = sessionid;
                }
            }

            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            JSONObject tokenJSON = new JSONObject(result);
//            tokenParam.put("headerName", tokenJSON.getString("headerName"));
//            tokenParam.put("token", tokenJSON.getString("token"));
//            tokenParam.put("time", new Long(System.currentTimeMillis()).toString());

            mHeaderName = tokenJSON.getString("headerName");
            mToken = tokenJSON.getString("token");
            mTime = System.currentTimeMillis();

            Log.d(TAG, "getTokenParam: " );
//            return tokenParam;
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
//        return tokenParam;
    }



}